<!-- TkiBarcode.vue -->
<template>
	<div class="tki-barcode">
		<!-- Canvas 用于绘制条形码 -->
		<!-- 注意：uniapp 小程序中必须使用 canvas-id，H5 可用 id -->
		<canvas
			:canvas-id="props.cid"
			:id="props.cid"
			class="tki-barcode-canvas"
			:style="{ width: canvasWidth + 20 + 'px', height: canvasHeight + 'px' }"
		/>
		<!-- 显示生成的条码图片 -->
		<img
			v-if="props.show && result && isH5"
			:src="result"
			:style="{ width: canvasWidth + 20 + 'px', height: canvasHeight + 'px' }"
			alt="barcode"
			@load="onImageLoad"
			@error="onImageError"
		/>
		<image
			v-else-if="props.show && result && !isH5"
			:src="result"
			:style="{ width: canvasWidth + 20 + 'px', height: canvasHeight + 'px' }"
			@load="onImageLoad"
			@error="onImageError"
		/>
	</div>
</template>

<script setup>
import { ref, onMounted, watch, nextTick, onBeforeUnmount } from 'vue';
import barCode from './barcode.js'; // 使用适配 UniApp 的版本

// -----------------------------
// Props 定义
// -----------------------------
const props = defineProps({
	show: {
		type: Boolean,
		default: true,
	},
	cid: {
		type: String,
		default: 'tki-barcode-canvas',
	},
	unit: {
		type: String,
		default: 'px',
	},
	val: {
		type: String,
		default: '1234567890128',
	},
	format: {
		type: String,
		default: 'CODE128',
	},
	options: {
		type: Object,
		default: () => ({}),
	},
	onVal: {
		type: Boolean,
		default: false,
	},
	loadMake: {
		type: Boolean,
		default: true,
	},
});

// -----------------------------
// 事件发射器
// -----------------------------
const emit = defineEmits(['result']);

// -----------------------------
// 响应式数据
// -----------------------------
const result = ref('');
const canvasWidth = ref(100);
const canvasHeight = ref(50);
const isH5 = ref(false);
const isMaking = ref(false);

// 默认配置
const defaultOptions = {
	width: 4,
	height: 120,
	displayValue: true,
	textAlign: 'center',
	textPosition: 'bottom',
	textMargin: 0,
	fontSize: 24,
	fontColor: '#000000',
	lineColor: '#000000',
	background: '#FFFFFF',
	margin: 0,
	marginTop: null,
	marginBottom: null,
	marginLeft: null,
	marginRight: null,
};

// upx 转 px 工具
const upx2px = upx => {
	try {
		const info = uni.getSystemInfoSync();
		const screenWidth = info.windowWidth;
		return (upx * screenWidth) / 750;
	} catch (e) {
		// 出错时返回默认值
		return upx;
	}
};

// 判断平台
const checkPlatform = () => {
	// #ifdef H5
	isH5.value = true;
	// #endif

	// #ifndef H5
	isH5.value = false;
	// #endif
};

// -----------------------------
// 核心方法：生成条码
// -----------------------------
const makeCode = () => {
	if (isMaking.value) return;
	isMaking.value = true;

	try {
		// 合并配置
		const mergedOptions = { ...defaultOptions, ...props.options };
		mergedOptions.format = props.format;
		mergedOptions.text = props.val;

		// 单位转换（upx → px）
		if (props.unit === 'upx') {
			const convert = upx2px;
			['width', 'height', 'fontSize'].forEach(key => {
				if (mergedOptions[key] !== undefined) {
					mergedOptions[key] = convert(mergedOptions[key]);
				}
			});
		}

		// 调用适配版 barCode，传入 canvasId 字符串
		barCode(
			props.cid, // 传 canvasId，如 'tki-barcode-canvas'
			mergedOptions,
			size => {
				canvasWidth.value = Math.max(size.width || 100, 100);
				canvasHeight.value = Math.max(size.height || 50, 50);
			},
			tempFilePath => {
				isMaking.value = false;
				if (tempFilePath) {
					result.value = tempFilePath;
					emit('result', tempFilePath);
				} else {
					console.error('条码生成失败');
					// 容错处理：即使生成失败也确保组件状态正确
					result.value = '';
					emit('result', null);
				}
			}
		);
	} catch (error) {
		isMaking.value = false;
		console.error('生成条码时发生错误:', error);
		result.value = '';
		emit('result', null);
	}
};

// -----------------------------
// 清除条码
// -----------------------------
const clearCode = () => {
	result.value = '';
	emit('result', '');
};

// -----------------------------
// 保存条码（H5：下载；小程序/App：保存到相册）
// -----------------------------
const saveCode = () => {
	if (!result.value) return;

	// H5 环境：下载
	// #ifdef H5
	const a = document.createElement('a');
	a.href = result.value;
	a.download = `barcode-${Date.now()}.png`;
	a.click();
	// #endif

	// 小程序/App 环境：保存到相册
	// #ifndef H5
	uni.saveImageToPhotosAlbum({
		filePath: result.value,
		success: () => {
			uni.showToast({ title: '已保存到相册', icon: 'success' });
		},
		fail: () => {
			uni.showToast({ title: '保存失败', icon: 'none' });
		},
	});
	// #endif
	return;
};

// -----------------------------
// 图片加载钩子（可选）
// -----------------------------
const onImageLoad = () => {
	// 可 emit 事件
};
const onImageError = () => {
	emit('result', null);
	console.error('条码图片加载失败');
};

// -----------------------------
// 生命周期 & 监听
// -----------------------------
onMounted(() => {
	checkPlatform();
	if (props.loadMake && props.val) {
		// 增加延时确保canvas已经挂载
		setTimeout(() => {
			makeCode();
		}, 200);
	}
});

watch(
	() => [props.val, props.options],
	() => {
		if (props.onVal) {
			// 增加延时避免频繁触发
			setTimeout(() => {
				makeCode();
			}, 100);
		}
	},
	{ deep: true }
);

// -----------------------------
// 暴露方法给父组件
// -----------------------------
defineExpose({
	makeCode,
	clearCode,
	saveCode,
});
</script>

<style scoped>
.tki-barcode {
	position: relative;
	display: inline-block;
}
.tki-barcode-canvas {
	position: absolute;
	top: -9999px;
	left: -9999px;
	pointer-events: none;
}
</style>
